﻿using KinonekoSoftware.CodariaDB.Documents.Shenanigans.Forum;
using KinonekoSoftware.Studio.Enums;
using KinonekoSoftware.Studio.Models.Shenanigans.Forums;
using ImageMSG = KinonekoSoftware.Studio.Models.Shenanigans.Forums.ImageMSG;

namespace KinonekoSoftware.Studio.Pages.Shenanigans
{
    [Flags]
    public enum ForumMSGCreationFlag : int
    {
        PlainText  = 0b000001,
        Image      = 0b000010,
        Attachment = 0b000100,
        Reply      = 0b001000,
    }


    partial class ForumEditorViewModel
    {

        private readonly EnumMaster<ForumMSGCreationFlag>       _creationType;
        private readonly EnumSingleSelect<ForumMSGCreationFlag> _plainTextMode;
        private readonly EnumSingleSelect<ForumMSGCreationFlag> _attachmentMode;
        private readonly EnumSingleSelect<ForumMSGCreationFlag> _imageMode;
        
        internal static  bool                             HasFlag(ForumMSGCreationFlag value, ForumMSGCreationFlag target) => (value & target) == target;


        private ForumMSG _currentEditing;
        private ForumMSG _creation;
        private bool     _isEditingPaneOpen;
        private bool     _isCreationEnable;

        private void DoEditMessageCommand(ForumMSG msg)
        {
            if (msg is null)
            {
                return;
            }

            CurrentEditing    = msg;
            IsEditingPaneOpen = true;
            RaiseUpdated(nameof(IsEditingMode));
        }

        private void DoReplyMessageCommand(ForumMSG msg)
        {
            if (msg is null)
            {
                return;
            }

            var reply = (ReplyMSG)Build(ForumMSGCreationFlag.Reply, msg.Target);

            //
            //
            _msgCreationFlag  = ForumMSGCreationFlag.Reply;
            CurrentCreation   = reply;
            IsCreationEnable  = false;
            IsEditingPaneOpen = true;

        }

        private async void DoRemoveMessageCommand(ForumMSG msg)
        {
            if (msg is null)
            {
                return;
            }

            if (!await RemoveItem())
            {
                return;
            }

            _ForumMessageIDMap.Remove(msg.Id);
            _ForumMessageCollection.Remove(msg);
            _discuss.Threads.Remove(msg.Target);
            PagedMessages.Remove(msg);

            //
            //
            SetDirtyState(true);
        }

        private async void DoAddImageToMessageCommand()
        {
            if (CurrentEditing is not ImageMSG && CurrentCreation is not ImageMSG)
            {
                return;
            }


            var r = await Platform.Image();

            if (!r.IsFinished)
            {
                return;
            }


            foreach (var result in r.Value)
            {
                if (CurrentEditing is ImageMSG ceImage)
                {

                    //
                    //
                    ceImage.Images.Add(result.Id);

                    //
                    //
                    ((ImageForumObject)ceImage.Target).Images.Add(result.Id);
                }
                else if (CurrentCreation is ImageMSG ccImage)
                {

                    //
                    //
                    ccImage.Images.Add(result.Id);

                    //
                    //
                    ((ImageForumObject)ccImage.Target).Images.Add(result.Id);
                }

                //
                //
                await _engine_image.WriteAsync(result.Id, result.Buffer);

                //
                //
                _engine_image.InsertOccupation(result.Id);
            }

            //
            //
            (CurrentEditing as ImageMSG)?.Update();
            (CurrentCreation as ImageMSG)?.Update();

            //
            //
            SetDirtyState(true);
        }

        private void DoShiftUpImageToMessageCommand(string image)
        {

            if (string.IsNullOrEmpty(image))
            {
                return;
            }

            if (CurrentEditing is not ImageMSG && CurrentCreation is not ImageMSG)
            {
                return;
            }

            if (CurrentEditing is ImageMSG ceImage)
            {
                //
                //
                ceImage.Images.ShiftUp(image);

                //
                //
                ((ImageForumObject)ceImage.Target).Images.ShiftUp(image);

                //
                //
                SetDirtyState(true);
            }
            else if (CurrentCreation is ImageMSG ccImage)
            {

                //
                //
                ccImage.Images.ShiftUp(image);

                //
                //
                ((ImageForumObject)ccImage.Target).Images.ShiftUp(image);

                //
                //
                SetDirtyState(true);
            }
        }

        private void DoShiftDownImageToMessageCommand(string image)
        {
            if (string.IsNullOrEmpty(image))
            {
                return;
            }

            if (CurrentEditing is not ImageMSG && CurrentCreation is not ImageMSG)
            {
                return;
            }

            if (CurrentEditing is ImageMSG ceImage)
            {
                //
                //
                ceImage.Images.ShiftDown(image);

                //
                //
                ((ImageForumObject)ceImage.Target).Images.ShiftDown(image);

                //
                //
                SetDirtyState(true);
            }
            else if (CurrentCreation is ImageMSG ccImage)
            {

                //
                //
                ccImage.Images.ShiftDown(image);

                //
                //
                ((ImageForumObject)ccImage.Target).Images.ShiftDown(image);

                //
                //
                SetDirtyState(true);
            }
        }

        private async void DoRemoveImageToMessageCommand(string image)
        {
            if (string.IsNullOrEmpty(image))
            {
                return;
            }

            if (CurrentEditing is not ImageMSG && CurrentCreation is not ImageMSG)
            {
                return;
            }

            if (!await RemoveItem())
            {
                return;
            }

            if (CurrentEditing is ImageMSG ceImage)
            {
                //
                //
                ceImage.Images.Remove(image);
                ceImage.Update();

                //
                //
                ((ImageForumObject)ceImage.Target).Images.Remove(image);

                //
                //
                _engine_image.RemoveOccupation(image);
                _engine_image.Delete(image);

                //
                //
                SetDirtyState(true);
            }
            else if (CurrentCreation is ImageMSG ccImage)
            {

                //
                //
                ccImage.Images.Remove(image);
                ccImage.Update();

                //
                //
                ((ImageForumObject)ccImage.Target).Images.Remove(image);

                //
                //
                _engine_image.RemoveOccupation(image);
                _engine_image.Delete(image);

                //
                //
                SetDirtyState(true);
            }

        }

        private void DoSendNewMessageCommand()
        {
            var msg = CurrentCreation;

            if (msg is null)
            {
                return;
            }

            //
            //
            Track(msg);

            if (PagedMessages.Count >= 25)
            {
                Page(_pageIndex + 1);
            }
            else
            {
                //
                //
                PagedMessages.Add(msg);
            }

            SetDirtyState(true);
            RaiseUpdated(nameof(PosterPostAmount));
            RaiseUpdated(nameof(MessageCount));

            if (_msgCreationFlag == ForumMSGCreationFlag.Reply)
            {
                _msgCreationFlag = ForumMSGCreationFlag.PlainText;
            }

            CurrentCreation = Build(_msgCreationFlag);
        }

        private void DoNewDiscussCommand(ForumMSG msg)
        {
            if (msg is null)
            {
                return;
            }

            //
            //
            var newDiscuss = ForumFactory.CreateDiscuss(_discuss, msg.Target);
            
            
            //
            // 设置为不可删除
            msg.Removable = false;
            msg.ForumID   = newDiscuss.Id;
            
            //
            //
            Platform.GetEngine<ForumEngine>().Add(newDiscuss);
            
            //
            //
            SetDirtyState(true);
        }

        /// <summary>
        /// 获取或设置 <see cref="IsEditingPaneOpen"/> 属性。
        /// </summary>
        public bool IsEditingPaneOpen
        {
            get => _isEditingPaneOpen;
            set
            {
                SetValue(ref _isEditingPaneOpen, value);

                if (value)
                {
                    if (IsEditingMode)
                    {

                    }
                    else
                    {
                        CurrentCreation = Build(_msgCreationFlag);
                    }

                    RaiseUpdated(nameof(IsEditingMode));
                }
                else
                {
                    if (IsEditingMode)
                    {
                        SetDirtyState(true);
                    }

                    CurrentCreation  = null;
                    CurrentEditing   = null;
                    IsCreationEnable = true;
                }
            }
        }


        public ForumMSG CurrentEditing
        {
            get => _currentEditing;
            set => SetValue(ref _currentEditing, value);
        }

        public ForumMSG CurrentCreation
        {
            get => _creation;
            set => SetValue(ref _creation, value);
        }

        public string ForumName
        {
            get => _discuss?.Name;
            set
            {
                _discuss.Name = value;
                SetDirtyState(true);
                RaiseUpdated();
            }
        }

        public string ForumIntro
        {
            get => _discuss?.Intro;
            set
            {
                _discuss.Intro = value;
                SetDirtyState(true);
                RaiseUpdated();
            }
        }

        public bool IsPlainTextCreationMode
        {
            get => _plainTextMode.Value;
            set => _plainTextMode.Value = value;
        }

        public bool IsImageCreationMode
        {

            get => _imageMode.Value;
            set => _imageMode.Value = value;
        }

        public bool IsAttachmentCreationMode
        {
            get => _attachmentMode.Value;
            set => _attachmentMode.Value = value;
        }


        /// <summary>
        /// 获取或设置 <see cref="IsCreationEnable"/> 属性。
        /// </summary>
        public bool IsCreationEnable
        {
            get => _isCreationEnable;
            set => SetValue(ref _isCreationEnable, value);
        }

        public bool IsEditingMode => _currentEditing is not null;

        public ICommandEX EditLikeAmountCommand          { get; }
        public ICommandEX EditDislikeAmountCommand       { get; }
        public ICommandEX NewDiscussCommand              { get; }
        public ICommandEX EditMessageCommand             { get; }
        public ICommandEX ReplyMessageCommand            { get; }
        public ICommandEX RemoveMessageCommand           { get; }
        public ICommandEX AddImageToMessageCommand       { get; }
        public ICommandEX ShiftUpImageToMessageCommand   { get; }
        public ICommandEX ShiftDownImageToMessageCommand { get; }
        public ICommandEX RemoveImageToMessageCommand    { get; }
        public ICommandEX SendNewMessageCommand          { get; }
    }
}